/**
 *  深拷贝与浅拷贝最大的区别是拷贝之后的对象修改会不会影响到拷贝之前的对象的属性
 * 深拷贝的几种方式及缺点
 * 1、ES6中的运算符（...）,明显的缺点是只能拷贝一层，无法拷贝深层的内容
 * 2、JSON.parse(JSON.stringify(Object)) 缺点是不能拷贝值为undefined和function
 * 3、循环和递归的方式
 */

let obj = {
  name: "xj",
  age: 20,
  height: undefined,
  eat: function () {},
  address: {
    cardId: 10086,
    addressName: "shenzheng",
  },
};

//1、运算符拷贝
// let newObj = { ...obj };
// newObj.address.cardId = 1008611;
// console.log(obj);

//3、循环和递归
function deepCopy(obj, hash = new WeakMap()) {
  if (obj == null) return obj;
  if (obj instanceof Date) return new Date(obj);
  if (obj instanceof RegExp) return new RegExp(obj);
  if (typeof obj != "object") return obj;
  if (hash.get(obj)) return obj; //防止循环引用的问题
  hash.set(obj, obj);
  let newObj = obj.constructor();
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      newObj[key] = deepCopy(obj[key], hash);
    }
  }
  return newObj;
}

let newObj = deepCopy(obj);
newObj.age = 18;
newObj.address.cardId = 8899;
console.log(obj, newObj);
